

module frv_core_top (
    input                   clk             ,
    input                   rst_n           ,
    // Program Downloader reset
    input                   pd_rst          ,
    input                   pd_wr           ,
    input [31:0]            pd_wdata        ,
    input [8:0]  pd_waddr        ,
    // ==========================================================================
    // Interrupt Interface
    input                   plic_int_vld    ,
    input                   clic_int_vld    ,
    // ==========================================================================
    // Device Bus Interface
    //waddr ch
    // output []
    output [5:0]    dev_awtid       ,
    output [31:0]               dev_awaddr      ,
    output [2:0]                dev_awprot      ,
    output                      dev_awvalid     , 
    input                       dev_awready     ,
    //wdata ch
    output [5:0]    dev_wtid        , 
    output [31:0]               dev_wdata       ,
    output [3:0]                dev_wstrb       ,
    output                      dev_wvalid      ,
    input                       dev_wready      ,
    //b resp ch
    output [5:0]    dev_btid        ,
    input  [1:0]                dev_bresp       ,
    input                       dev_bvalid      ,
    output                      dev_bready      ,
    //raddr ch
    output [5:0]    dev_artid       ,
    output [31:0]               dev_araddr      ,
    output [2:0]                dev_arprot      ,
    output                      dev_arvalid     ,
    input                       dev_arready     ,
    //rdata ch
    output [5:0]    dev_rtid        ,
    input  [31:0]               dev_rdata       ,
    input  [1:0]                dev_rresp       ,
    input                       dev_rvalid      ,
    output                      dev_rready           
);

wire                       imem_req      ;
wire [31:0]                imem_addr     ;
wire [31:0]                imem_data     ;
wire                       imem_vld      ;
wire                       imem_flush    ;
wire                       bru_flush     ;
wire                       bru_update_vld;
wire [31:0]                bru_btb_taddr ;
// wire [31:0]                bru_pc_data   ;
wire                       bru_taken     ;
wire [3:0]                 bru_bht_val   ;
wire [31:0]                bru_pht_val   ;
// wire                       exp_flush     ;
wire [4:0]                 exp_code      ;
wire [31:0]                exp_taddr     ;
wire                       ib_rreq       ;
wire                       ib_inst_vld   ;
wire [31:0]                ib_inst_data  ;
wire [31:0]                ib_pc_data    ;
wire                       ib_exp_vld    ;
wire [4:0]                 ib_exp_code   ;
wire [31:0]                ib_bp_taddr   ;
wire                       ib_bp_taken   ;
wire [3:0]                 ib_bp_bhtv    ;
wire [31:0]                ib_bp_phtv    ;

wire                       exp_flush       ; // Exception Flush
assign exp_flush = 0;
//Foward Interface
wire                       lsu_fwd_vld     ;
wire                       lsu_fwd_rd_vld  ;
wire [5:0]     lsu_fwd_inst_id ;
wire                       bru_fwd_vld     ;
wire                       bru_fwd_rd_vld  ;
wire [5:0]     bru_fwd_inst_id ;
wire                       alu_fwd_vld     ;
wire                       alu_fwd_rd_vld  ;
wire [5:0]     alu_fwd_inst_id ;

// =============================
// Issue Queue Interface
wire                      isu_ready        ;// Issue Queue Ready , when issue queue is full , isu_ready will be pull up
wire                      isq_wreq         ;// Issue Queue Write Request,The Inst Entry must be valid before push into ISQ
wire[31:0]                isq_inst_data    ;
wire[5:0]     isq_inst_id      ;
wire                      isq_exp_vld      ;
wire[4:0]                 isq_exp_code     ; 
wire[31:0]                isq_pc_data      ;
//ALU Control Interface
wire                      isq_alu_vld      ; 
wire                      isq_alu_land     ; 
wire                      isq_alu_lor      ; 
wire                      isq_alu_lxor     ; 
wire                      isq_alu_sll      ; 
wire                      isq_alu_srl      ;
wire                      isq_alu_sra      ;
wire                      isq_alu_add      ;
wire                      isq_alu_sub      ;
wire                      isq_alu_slt      ;
wire                      isq_alu_unsign   ;
//Branch Control Interface
wire                      isq_bru_vld     ;
wire                      isq_bru_beq     ;
wire                      isq_bru_bne     ;
wire                      isq_bru_blt     ;
wire                      isq_bru_bge     ;
wire                      isq_bru_jal     ;
wire                      isq_bru_jalr    ;
wire [31:0]               isq_bp_taddr    ; // bp target addr
wire                      isq_bp_taken    ; // bp taken
wire [3:0]                isq_bp_bhtv     ; // BHT Entry Value
wire [31:0]               isq_bp_phtv     ; // PHT Entry Value
//LSU Control Interface
wire                      isq_lsu_vld     ;
wire                      isq_lsu_unsign  ;
wire                      isq_lsu_load    ;
wire                      isq_lsu_store   ;
wire                      isq_lsu_word    ;
wire                      isq_lsu_half    ;
wire                      isq_lsu_byte    ;
//MDU Control Interface
//TODO
//CSR Control Interface
wire                      isq_csr_vld     ;
wire                      isq_csr_write   ;
wire                      isq_csr_set     ;
wire                      isq_csr_clr     ; // CSR Clear
//Operation number Interface
wire                      isq_rs1_vld     ;
wire[5:0]     isq_rs1_ind     ;
wire                      isq_rs1_type    ;
wire                      isq_rs1_ready   ;
wire                      isq_rs2_vld     ;
wire[5:0]     isq_rs2_ind     ;
wire                      isq_rs2_type    ;
wire                      isq_rs2_ready   ;
wire                      isq_imm_vld     ;
wire [31:0]               isq_imm_data    ; // here we can compress the width
wire                      isq_rd_vld      ;
wire [4:0]                isq_rd_ind      ;
// wire [5:0]    isq_rdm_ind     ;
wire                      isq_pc_used     ;// jal and auipc will use the pc value    

//Function Port
wire                     alu_req          ;
wire                     alu_ctrl_land    ;
wire                     alu_ctrl_lor     ;
wire                     alu_ctrl_lxor    ;
wire                     alu_ctrl_sll     ;
wire                     alu_ctrl_srl     ;
wire                     alu_ctrl_sra     ;
wire                     alu_ctrl_add     ;
wire                     alu_ctrl_sub     ;
wire                     alu_ctrl_slt     ;
wire                     alu_ctrl_unsign  ;
wire[5:0]    alu_inst_id      ; // Instruction ID                    
wire[31:0]               alu_op1_val      ;
wire[31:0]               alu_op2_val      ;
wire                     alu_resp_vld     ;
wire[31:0]               alu_resp_rd_val  ;    
wire[5:0]    alu_resp_inst_id ;
// ==========================================================================
//BRU Interface
wire                      bru_req         ;
wire [5:0]    bru_inst_id     ; // Instruction ID  
wire                      bru_ctrl_beq    ;
wire                      bru_ctrl_bne    ;
wire                      bru_ctrl_blt    ;
wire                      bru_ctrl_bge    ;
wire                      bru_ctrl_jal    ;
wire                      bru_ctrl_jalr   ;
//BRU Operation Num
wire [31:0]               bru_pc_data     ;
wire [31:0]               bru_op1_val     ;
wire [31:0]               bru_op2_val     ;
wire                      bru_rd_vld      ;
wire [31:0]               bru_imm_val     ;    
wire [31:0]               bru_bp_taddr    ; // bp target addr
wire                      bru_bp_taken    ; // bp taken
wire [3:0]                bru_bp_bhtv     ; // BHT Entry Value
wire [31:0]               bru_bp_phtv     ; // PHT Entry Value    
//BRU Response
wire [5:0]    bru_resp_inst_id;
wire                      bru_resp_taken  ;
wire                      bru_resp_vld    ;
wire                      bru_resp_rd_vld ;
wire [31:0]               bru_resp_rd_val ;
wire [31:0]               bru_caddr_val   ;    
// ==========================================================================
//LSU Interface                             
wire                      lsu_req         ;
wire                      lsu_ctrl_unsign ;
wire                      lsu_ctrl_load   ;
wire                      lsu_ctrl_store  ;
wire                      lsu_ctrl_word   ;
wire                      lsu_ctrl_half   ;
wire                      lsu_ctrl_byte   ;
wire [5:0]    lsu_inst_id     ; // Instruction ID  
//Store Instruction Retire 
wire                      lsu_stor_retire ;
wire [5:0]    lsu_stor_rid    ;   
//LSU Operation Number
wire [31:0]               lsu_op1_val     ;
wire [31:0]               lsu_op2_val     ;    
wire [31:0]               lsu_store_data  ;

wire                      dmem_req     ;
wire [5:0]    dmem_req_tid ; // request transaction id , ignore it before we implement cache
wire [31:0]               dmem_addr    ; 
wire                      dmem_wren    ;
wire [3:0]                dmem_strb    ;

wire [31:0]               dmem_wdata   ;
wire [31:0]               dmem_rdata   ;
wire                      dmem_ack     ; // Cache will give ACK to LSU if cache hit happen
wire                      dmem_flush   ; //ignore

//LSU Response
wire [5:0]    lsu_resp_inst_id;
wire                      lsu_resp_vld    ;
wire                      lsu_resp_rd_vld ;
wire [31:0]               lsu_resp_rd_val ; //rd value    
wire                      lsu_exp_vld     ;  //ignore it when exception feature is not implemented
wire                      lsu_ready       ;

wire                      ret_flush_rles  ; //Flush Release
wire                      ret_rd_req      ;
wire [5:0]    ret_inst_id     ;


frv_ifu_top _frv_ifu_top(
.clk                (clk           ),
.rst_n              (rst_n         ),
.pd_rst             (pd_rst        ),
.imem_req           (imem_req      ),
.imem_addr          (imem_addr     ),
.imem_data          (imem_data     ),
.imem_vld           (imem_vld      ), // ignore it when the cache module is not ready
.imem_flush         (imem_flush    ),
.bru_flush          (bru_flush     ), // vld when branch prediction fail
.bru_update_vld     (bru_update_vld), // vld when branch behavior happen 
.bru_btb_taddr      (bru_caddr_val ), // BTB target addr value
.bru_pc_data        (bru_pc_data   ), 
.bru_taken          (bru_resp_taken),       
.bru_bht_val        (bru_bht_val   ), // BHT Entry Value
.bru_pht_val        (bru_pht_val   ), // PHT Entry Value
.exp_flush          (exp_flush     ), 
.exp_code           (exp_code      ), 
.exp_taddr          (exp_taddr     ),
.ib_rreq            (ib_rreq       ),  
.ib_inst_vld        (ib_inst_vld   ),  
.ib_inst_data       (ib_inst_data  ),  
.ib_pc_data         (ib_pc_data    ),  
.ib_exp_vld         (ib_exp_vld    ), 
.ib_exp_code        (ib_exp_code   ), 
.ib_bp_taddr        (ib_bp_taddr   ), // bp target addr
.ib_bp_taken        (ib_bp_taken   ), 
.ib_bp_bhtv         (ib_bp_bhtv    ), // BHT Entry Value
.ib_bp_phtv         (ib_bp_phtv    )  // PHT Entry Value
);

frv_idu_top _frv_idu_top(
.clk                (clk           ),
.rst_n              (rst_n         ),
.pd_rst             (pd_rst        ),
.exp_flush          (exp_flush     ), // Exception Flush
.bru_flush          (bru_flush     ), // Branch Prediction failed Flush
.ret_flush_stall    (ret_flush_stall),
.ret_rd_req         (ret_rd_req    ),
.ret_inst_id        (ret_inst_id   ), // ROB Read Pointer Val 
.ret_flush_rles     (ret_flush_rles), 
.lsu_fwd_vld        (lsu_fwd_vld   ),
.lsu_fwd_rd_vld     (lsu_fwd_rd_vld),
.lsu_fwd_inst_id    (lsu_fwd_inst_id),
.bru_fwd_vld        (bru_fwd_vld   ),
.bru_fwd_rd_vld     (bru_fwd_rd_vld),
.bru_fwd_inst_id    (bru_fwd_inst_id),
.alu_fwd_vld        (alu_fwd_vld   ),
.alu_fwd_rd_vld     (alu_fwd_rd_vld),
.alu_fwd_inst_id    (alu_fwd_inst_id),
.ib_rreq            (ib_rreq       ), // Inst queue request
.ib_inst_vld        (ib_inst_vld   ), 
.ib_inst_data       (ib_inst_data  ),
.ib_pc_data         (ib_pc_data    ),
.ib_exp_vld         (ib_exp_vld    ),
.ib_exp_code        (ib_exp_code   ),
.ib_bp_taddr        (ib_bp_taddr   ), // bp target addr
.ib_bp_taken        (ib_bp_taken   ), 
.ib_bp_bhtv         (ib_bp_bhtv    ), // BHT Entry Value
.ib_bp_phtv         (ib_bp_phtv    ), // PHT Entry Value
.isu_ready          (isu_ready     ), // Issue Queue Ready , when issue queue is full , isu_ready will be pull up
.isq_wreq           (isq_wreq      ), // Issue Queue Write Request,The Inst Entry must be valid before push into ISQ
.isq_inst_data      (isq_inst_data ), 
.isq_inst_id        (isq_inst_id   ), 
.isq_exp_vld        (isq_exp_vld   ), 
.isq_exp_code       (isq_exp_code  ),  
.isq_pc_data        (isq_pc_data   ), 
.isq_alu_vld        (isq_alu_vld   ), 
.isq_alu_land       (isq_alu_land  ), 
.isq_alu_lor        (isq_alu_lor   ), 
.isq_alu_lxor       (isq_alu_lxor  ), 
.isq_alu_sll        (isq_alu_sll   ), 
.isq_alu_srl        (isq_alu_srl   ),
.isq_alu_sra        (isq_alu_sra   ),
.isq_alu_add        (isq_alu_add   ),
.isq_alu_sub        (isq_alu_sub   ),
.isq_alu_slt        (isq_alu_slt   ),
.isq_alu_unsign     (isq_alu_unsign),
.isq_bru_vld        (isq_bru_vld   ),
.isq_bru_beq        (isq_bru_beq   ),
.isq_bru_bne        (isq_bru_bne   ),
.isq_bru_blt        (isq_bru_blt   ),
.isq_bru_bge        (isq_bru_bge   ),
.isq_bru_jal        (isq_bru_jal   ),
.isq_bru_jalr       (isq_bru_jalr  ),
.isq_bp_taddr       (isq_bp_taddr  ), // bp target addr
.isq_bp_taken       (isq_bp_taken  ), // bp taken
.isq_bp_bhtv        (isq_bp_bhtv   ), // BHT Entry Value
.isq_bp_phtv        (isq_bp_phtv   ), // PHT Entry Value
.isq_lsu_vld        (isq_lsu_vld   ),
.isq_lsu_unsign     (isq_lsu_unsign),
.isq_lsu_load       (isq_lsu_load  ),
.isq_lsu_store      (isq_lsu_store ),
.isq_lsu_word       (isq_lsu_word  ),
.isq_lsu_half       (isq_lsu_half  ),
.isq_lsu_byte       (isq_lsu_byte  ),
.isq_csr_vld        (isq_csr_vld   ),
.isq_csr_write      (isq_csr_write ),
.isq_csr_set        (isq_csr_set   ),
.isq_csr_clr        (isq_csr_clr   ), // CSR Clear
.isq_rs1_vld        (isq_rs1_vld   ),
.isq_rs1_ind        (isq_rs1_ind   ),
.isq_rs1_type       (isq_rs1_type  ),
.isq_rs1_ready      (isq_rs1_ready ),
.isq_rs2_vld        (isq_rs2_vld   ),
.isq_rs2_ind        (isq_rs2_ind   ),
.isq_rs2_type       (isq_rs2_type  ),
.isq_rs2_ready      (isq_rs2_ready ),
.isq_imm_vld        (isq_imm_vld   ),
.isq_imm_data       (isq_imm_data  ), // here we can compress the width
.isq_rd_vld         (isq_rd_vld    ),
.isq_rd_ind         (isq_rd_ind    ),
// .isq_rdm_ind        (isq_rdm_ind   ),
.isq_pc_used        (isq_pc_used   ) // jal and auipc will use the pc value    
);
wire [5:0] exp_flush_tid;
assign exp_flush_tid = 0;
frv_isu_top _frv_isu_top(
.clk                (clk             ),
.rst_n              (rst_n           ),
.pd_rst             (pd_rst          ),
.exp_flush          (exp_flush       ), // Exception Flush
.exp_flush_tid      (exp_flush_tid   ), // Exception Flush ID
.bru_flush          (bru_flush       ), // Branch Prediction failed Flush
.isu_ready          (isu_ready       ), // Issue Queue Ready , when issue queue is full , isu_ready will be pull up
.isq_wreq           (isq_wreq        ), // Issue Queue Request
.isq_inst_data      (isq_inst_data   ),
.isq_inst_id        (isq_inst_id     ),
.isq_exp_vld        (isq_exp_vld     ),
.isq_exp_code       (isq_exp_code    ),
.isq_pc_data        (isq_pc_data     ),
.isq_alu_vld        (isq_alu_vld     ),
.isq_alu_land       (isq_alu_land    ),
.isq_alu_lor        (isq_alu_lor     ),
.isq_alu_lxor       (isq_alu_lxor    ),
.isq_alu_sll        (isq_alu_sll     ),
.isq_alu_srl        (isq_alu_srl     ),
.isq_alu_sra        (isq_alu_sra     ),
.isq_alu_add        (isq_alu_add     ),
.isq_alu_sub        (isq_alu_sub     ),
.isq_alu_slt        (isq_alu_slt     ),
.isq_alu_unsign     (isq_alu_unsign  ),
.isq_bru_vld        (isq_bru_vld     ),
.isq_bru_beq        (isq_bru_beq     ),
.isq_bru_bne        (isq_bru_bne     ),
.isq_bru_blt        (isq_bru_blt     ),
.isq_bru_bge        (isq_bru_bge     ),
.isq_bru_jal        (isq_bru_jal     ),
.isq_bru_jalr       (isq_bru_jalr    ),
.isq_bp_taddr       (isq_bp_taddr    ), // bp target addr
.isq_bp_taken       (isq_bp_taken    ), // bp taken
.isq_bp_bhtv        (isq_bp_bhtv     ), // BHT Entry Value
.isq_bp_phtv        (isq_bp_phtv     ), // PHT Entry Value
.isq_lsu_vld        (isq_lsu_vld     ),
.isq_lsu_unsign     (isq_lsu_unsign  ),
.isq_lsu_load       (isq_lsu_load    ),
.isq_lsu_store      (isq_lsu_store   ),
.isq_lsu_word       (isq_lsu_word    ),
.isq_lsu_half       (isq_lsu_half    ),
.isq_lsu_byte       (isq_lsu_byte    ),
.isq_csr_vld        (isq_csr_vld     ),
.isq_csr_write      (isq_csr_write   ),
.isq_csr_set        (isq_csr_set     ),
.isq_csr_clr        (isq_csr_clr     ), // CSR Clear
.isq_rs1_vld        (isq_rs1_vld     ),
.isq_rs1_ind        (isq_rs1_ind     ),
.isq_rs1_rdy        (isq_rs1_ready   ),    
.isq_rs1_type       (isq_rs1_type    ),
.isq_rs2_vld        (isq_rs2_vld     ),
.isq_rs2_ind        (isq_rs2_ind     ),
.isq_rs2_rdy        (isq_rs2_ready   ),    
.isq_rs2_type       (isq_rs2_type    ),
.isq_imm_vld        (isq_imm_vld     ),
.isq_imm_data       (isq_imm_data    ), // here we can compress the width
.isq_rd_vld         (isq_rd_vld      ),
.isq_rd_ind         (isq_rd_ind      ), // Reg Destenation Index
// .isq_rdm_ind        (isq_rdm_ind     ),
.isq_pc_used        (isq_pc_used     ), // jal and auipc will use the pc value    
.alu_req            (alu_req         ),
.alu_ctrl_land      (alu_ctrl_land   ),
.alu_ctrl_lor       (alu_ctrl_lor    ),
.alu_ctrl_lxor      (alu_ctrl_lxor   ),
.alu_ctrl_sll       (alu_ctrl_sll    ),
.alu_ctrl_srl       (alu_ctrl_srl    ),
.alu_ctrl_sra       (alu_ctrl_sra    ),
.alu_ctrl_add       (alu_ctrl_add    ),
.alu_ctrl_sub       (alu_ctrl_sub    ),
.alu_ctrl_slt       (alu_ctrl_slt    ),
.alu_ctrl_unsign    (alu_ctrl_unsign ),
.alu_inst_id        (alu_inst_id     ), // Instruction ID                   
.alu_op1_val        (alu_op1_val     ),
.alu_op2_val        (alu_op2_val     ),
.alu_resp_vld       (alu_resp_vld    ),
.alu_resp_rd_val    (alu_resp_rd_val ),    
.alu_resp_inst_id   (alu_resp_inst_id),
.bru_req            (bru_req         ),
.bru_inst_id        (bru_inst_id     ), // Instruction ID  
.bru_ctrl_beq       (bru_ctrl_beq    ),
.bru_ctrl_bne       (bru_ctrl_bne    ),
.bru_ctrl_blt       (bru_ctrl_blt    ),
.bru_ctrl_bge       (bru_ctrl_bge    ),
.bru_ctrl_jal       (bru_ctrl_jal    ),
.bru_ctrl_jalr      (bru_ctrl_jalr   ),
.bru_pc_data        (bru_pc_data     ),
.bru_op1_val        (bru_op1_val     ),
.bru_op2_val        (bru_op2_val     ),
.bru_rd_vld         (bru_rd_vld      ),
.bru_imm_val        (bru_imm_val     ),    
.bru_bp_taddr       (bru_bp_taddr    ), // bp target addr
.bru_bp_taken       (bru_bp_taken    ), // bp taken
.bru_bp_bhtv        (bru_bp_bhtv     ), // BHT Entry Value
.bru_bp_phtv        (bru_bp_phtv     ), // PHT Entry Value    
.bru_resp_inst_id   (bru_resp_inst_id),
.bru_resp_vld       (bru_resp_vld    ),
.bru_resp_rd_vld    (bru_resp_rd_vld ),
.bru_resp_rd_val    (bru_resp_rd_val ),                              
.lsu_req            (lsu_req         ),
.lsu_ctrl_unsign    (lsu_ctrl_unsign ),
.lsu_ctrl_load      (lsu_ctrl_load   ),
.lsu_ctrl_store     (lsu_ctrl_store  ),
.lsu_ctrl_word      (lsu_ctrl_word   ),
.lsu_ctrl_half      (lsu_ctrl_half   ),
.lsu_ctrl_byte      (lsu_ctrl_byte   ),
.lsu_inst_id        (lsu_inst_id     ), // Instruction ID  
.lsu_stor_retire    (lsu_stor_retire ),
.lsu_stor_rid       (lsu_stor_rid    ),   
.lsu_op1_val        (lsu_op1_val     ),
.lsu_op2_val        (lsu_op2_val     ),    
.lsu_store_data     (lsu_store_data  ),
.lsu_resp_inst_id   (lsu_resp_inst_id),
.lsu_resp_vld       (lsu_resp_vld    ),
.lsu_resp_rd_vld    (lsu_resp_rd_vld ),
.lsu_resp_rd_val    (lsu_resp_rd_val ), //rd value    
.lsu_exp_vld        (lsu_exp_vld     ),  //ignore it when exception feature is not implemented
.lsu_ready          (lsu_ready       ),
.ret_flush_rles     (ret_flush_rles  ), //Flush Release
.ret_rd_req         (ret_rd_req      ),
.ret_inst_id        (ret_inst_id     )
);

assign lsu_fwd_vld      = lsu_resp_vld    ;
assign lsu_fwd_rd_vld   = lsu_resp_rd_vld ;
assign lsu_fwd_inst_id  = lsu_resp_inst_id;
assign bru_fwd_vld      = bru_resp_vld    ;
assign bru_fwd_rd_vld   = bru_resp_rd_vld ;
assign bru_fwd_inst_id  = bru_resp_inst_id;
assign alu_fwd_vld      = alu_resp_vld    ;
assign alu_fwd_rd_vld   = alu_resp_vld ;
assign alu_fwd_inst_id  = alu_resp_inst_id;

frv_iu_alu _frv_iu_alu(
.clk                 (clk             ),
.rst_n               (rst_n           ),
.pd_rst              (pd_rst          ),
.alu_req             (alu_req         ),
.alu_inst_id         (alu_inst_id     ),
.alu_ctrl_land       (alu_ctrl_land   ),
.alu_ctrl_lor        (alu_ctrl_lor    ),
.alu_ctrl_lxor       (alu_ctrl_lxor   ),
.alu_ctrl_sll        (alu_ctrl_sll    ),
.alu_ctrl_srl        (alu_ctrl_srl    ),
.alu_ctrl_sra        (alu_ctrl_sra    ),
.alu_ctrl_add        (alu_ctrl_add    ),
.alu_ctrl_sub        (alu_ctrl_sub    ),
.alu_ctrl_slt        (alu_ctrl_slt    ),
.alu_ctrl_unsign     (alu_ctrl_unsign ),              
.alu_op1_val         (alu_op1_val     ),
.alu_op2_val         (alu_op2_val     ),
.alu_resp_vld        (alu_resp_vld    ),
.alu_resp_inst_id    (alu_resp_inst_id),   
.alu_resp_rd_val     (alu_resp_rd_val )    
);


frv_iu_bru _frv_iu_bru(
.clk                    (clk             ),
.rst_n                  (rst_n           ),
.pd_rst                 (pd_rst          ),
.bru_req                (bru_req         ),
.bru_inst_id            (bru_inst_id     ), // Instruction ID  
.bru_ctrl_beq           (bru_ctrl_beq    ),
.bru_ctrl_bne           (bru_ctrl_bne    ),
.bru_ctrl_blt           (bru_ctrl_blt    ),
.bru_ctrl_bge           (bru_ctrl_bge    ),
.bru_ctrl_jal           (bru_ctrl_jal    ),
.bru_ctrl_jalr          (bru_ctrl_jalr   ),                         
.bru_pc_data            (bru_pc_data     ),
.bru_op1_val            (bru_op1_val     ),
.bru_op2_val            (bru_op2_val     ),
.bru_rd_vld             (bru_rd_vld      ),
.bru_imm_val            (bru_imm_val     ),    
.bru_bp_taddr           (bru_bp_taddr    ), // bp target addr
.bru_bp_taken           (bru_bp_taken    ), // bp taken
.bru_bp_bhtv            (bru_bp_bhtv     ), // BHT Entry Value
.bru_bp_phtv            (bru_bp_phtv     ), // PHT Entry Value    
.bru_resp_inst_id       (bru_resp_inst_id),
.bru_resp_vld           (bru_resp_vld    ),
.bru_resp_taken         (bru_resp_taken  ),
.bru_resp_rd_vld        (bru_resp_rd_vld ),
.bru_resp_rd_val        (bru_resp_rd_val ),
.bru_caddr_val          (bru_caddr_val   ), //correct Address value
.bru_flush              (bru_flush       )    
);

wire                      ddr_req         ;
wire [5:0]    ddr_req_tid     ; // request transaction id , ignore it before we implement cache
wire [31:0]               ddr_addr        ; 
wire                      ddr_ack         ;
wire[5:0]     ddr_ack_tid     ;

assign ddr_ack = 0;
assign ddr_ack_tid = 0;

frv_lsu_top _frv_lsu_top(
.clk                    (clk             ),
.rst_n                  (rst_n           ),
.pd_rst                 (pd_rst          ),
.lsu_req                (lsu_req         ),
.lsu_ready              (lsu_ready       ),
.lsu_ctrl_unsign        (lsu_ctrl_unsign ),
.lsu_ctrl_load          (lsu_ctrl_load   ),
.lsu_ctrl_store         (lsu_ctrl_store  ),
.lsu_ctrl_word          (lsu_ctrl_word   ),
.lsu_ctrl_half          (lsu_ctrl_half   ),
.lsu_ctrl_byte          (lsu_ctrl_byte   ),
.lsu_inst_id            (lsu_inst_id     ), // Instruction ID  \
.lsu_flush              (bru_flush       ),
.lsu_flush_id           (bru_resp_inst_id),
.lsu_op1_val            (lsu_op1_val     ),
.lsu_op2_val            (lsu_op2_val     ),    
.lsu_store_data         (lsu_store_data  ),
.lsu_stor_retire        (lsu_stor_retire ),
.lsu_stor_rid           (lsu_stor_rid    ),
.lsu_resp_inst_id       (lsu_resp_inst_id),
.lsu_resp_vld           (lsu_resp_vld    ), 
.lsu_resp_rd_vld        (lsu_resp_rd_vld ),  
.lsu_resp_rd_val        (lsu_resp_rd_val ), //rd value    
.lsu_exp_vld            (lsu_exp_vld     ), //ignore it when exception feature is not implemented
.dmem_req               (dmem_req        ),
.dmem_req_tid           (dmem_req_tid    ), // request transaction id , ignore it before we implement cache
.dmem_addr              (dmem_addr       ), 
.dmem_wren              (dmem_wren       ),
.dmem_strb              (dmem_strb       ),
.dmem_wdata             (dmem_wdata      ),
.dmem_rdata             (dmem_rdata      ),
.dmem_ack               (dmem_ack        ), // Cache will give ACK to LSU if cache hit happen
.dmem_flush             (dmem_flush      ), //ignore
.ddr_req                (ddr_req         ),
.ddr_req_tid            (ddr_req_tid     ), // request transaction id , ignore it before we implement cache
.ddr_addr               (ddr_addr        ), 
.ddr_ack                (ddr_ack         ),
.ddr_ack_tid            (ddr_ack_tid     ),
.dev_awtid              (dev_awtid       ),
.dev_awaddr             (dev_awaddr      ),
.dev_awprot             (dev_awprot      ),
.dev_awvalid            (dev_awvalid     ), 
.dev_awready            (dev_awready     ),
.dev_wtid               (dev_wtid        ), 
.dev_wdata              (dev_wdata       ),
.dev_wstrb              (dev_wstrb       ),
.dev_wvalid             (dev_wvalid      ),
.dev_wready             (dev_wready      ),
.dev_btid               (dev_btid        ),
.dev_bresp              (dev_bresp       ),
.dev_bvalid             (dev_bvalid      ),
.dev_bready             (dev_bready      ),
.dev_artid              (dev_artid       ),
.dev_araddr             (dev_araddr      ),
.dev_arprot             (dev_arprot      ),
.dev_arvalid            (dev_arvalid     ),
.dev_arready            (dev_arready     ),
.dev_rtid               (dev_rtid        ),
.dev_rdata              (dev_rdata       ),
.dev_rresp              (dev_rresp       ),
.dev_rvalid             (dev_rvalid      ),
.dev_rready             (dev_rready      )     
);

dffr #(.DW(1)) dmem_debug_ack_ff(clk,rst_n,1'b1,dmem_req,dmem_ack);


frv_bdram_32_fpga _frv_bdram_32_fpga (
  .clka     (clk),    // input wire clka
  .ena      (imem_req),      // input wire ena
  .wea      (0),      // input wire [3 : 0] wea
  .addra    (imem_addr[17:2]),  // input wire [15 : 0] addra
  .dina     (0),    // input wire [31 : 0] dina
  .douta    (imem_data),  // output wire [31 : 0] douta
  .clkb     (clk),    // input wire clkb
  .enb      (dmem_req),      // input wire enb
  .web      ({4{dmem_wren}} & dmem_strb),      // input wire [3 : 0] web
  .addrb    (dmem_addr[17:2]),  // input wire [15 : 0] addrb
  .dinb     (dmem_wdata),    // input wire [31 : 0] dinb
  .doutb    (dmem_rdata)   // output wire [31 : 0] doutb
);


// frv_bdram_32 _frv_bdram_32(
// .clk            (clk),
// .addra          (imem_addr[17:2]),
// .douta          (imem_data),
// .addr           (dmem_addr[17:2]),
// .din            (dmem_wdata),
// .wen            ({4{dmem_wren}} & dmem_strb),
// .dout           (dmem_rdata)
// );


endmodule

